package org.fastsyncer.rest.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.entity.DataSourceConfig;
import org.fastsyncer.common.entity.DataSourceConnector;
import org.fastsyncer.common.entity.RestResult;
import org.fastsyncer.common.util.JsonUtil;
import org.fastsyncer.framework.connector.Connector;
import org.fastsyncer.framework.manager.Manager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/driver")
public class DriverController {

	private static final Logger logger = LoggerFactory.getLogger(DriverController.class);

	@RequestMapping("/page/{opr}")
	public String driverAdd(HttpServletRequest request, ModelMap model, @PathVariable("opr") String opr) {
		String dirverName = request.getParameter("dirverName");
		if (!StringUtils.isBlank(dirverName)) {
			try {
				Object driver = Manager.getInstance().getDriver(dirverName);
				model.addAttribute("dirver", driver);
				model.addAttribute("dirverJson", JsonUtil.objToJson(driver));
			} catch (Exception e) {
				logger.error(e.getLocalizedMessage(), e.getClass());
			}
		}
		return "driver/" + opr;
	}

	@RequestMapping(value = "/getDataSourceConnector", method = RequestMethod.POST)
	@ResponseBody
	public RestResult getDataSourceConnector(HttpServletResponse response, DataSourceConfig config) {
		try {
			DataSourceConnector dataSourceConnector = Connector.getInstance().getDataSourceConnector(config);
			return RestResult.restSuccess(dataSourceConnector);
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}
	
	/**
	 * 查询是否在运行
	 * @param name 驱动名称
	 * @return true:正在运行，否则false
	 */
	@RequestMapping(value = "/isRun", method = RequestMethod.POST)
	@ResponseBody
	public RestResult isRun(@RequestParam(value = "name") String name) {
		try {
			return RestResult.restSuccess(Manager.getInstance().isRun(name));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ResponseBody
	public RestResult add(HttpServletResponse response, @RequestParam(value = "mapping") String mapping) {
		try {
			logger.info(mapping);
			if (StringUtils.isBlank(mapping)) {
				throw new NullPointerException("mapping参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().add(mapping));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@ResponseBody
	public RestResult update(HttpServletResponse response, @RequestParam(value = "mapping") String mapping) {
		try {
			logger.info(mapping);
			if (StringUtils.isBlank(mapping)) {
				throw new NullPointerException("mapping参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().update(mapping));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping(value = "/enable", method = RequestMethod.POST)
	@ResponseBody
	public RestResult enable(HttpServletResponse response, @RequestParam(value = "name") String name) {
		try {
			if (StringUtils.isBlank(name)) {
				throw new NullPointerException("name参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().enable(name));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	@ResponseBody
	public RestResult delete(HttpServletResponse response, @RequestParam(value = "name") String name) {
		try {
			if (StringUtils.isBlank(name)) {
				throw new NullPointerException("name参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().delete(name));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping(value = "/start", method = RequestMethod.POST)
	@ResponseBody
	public RestResult start(HttpServletResponse response, @RequestParam(value = "name") String name) {
		try {
			if (StringUtils.isBlank(name)) {
				throw new NullPointerException("name参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().start(name));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}
	
	@RequestMapping(value = "/stop", method = RequestMethod.POST)
	@ResponseBody
	public RestResult stop(HttpServletResponse response, @RequestParam(value = "name") String name) {
		try {
			if (StringUtils.isBlank(name)) {
				throw new NullPointerException("name参数不能为空！");
			}
			return RestResult.restSuccess(Manager.getInstance().stop(name));
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
			return RestResult.restFail(e.getLocalizedMessage());
		}
	}

	@RequestMapping("/download")
	public String download(HttpServletRequest request, HttpServletResponse response,
			@RequestParam(value = "name") String name) {
		response.setCharacterEncoding("utf-8");
		response.setContentType("multipart/form-data");
		response.setHeader("Content-Disposition", "attachment;fileName=" + name + ".txt");
		try {
			File mappingLog = Manager.getInstance().getMappingLog(name);
			InputStream inputStream = new FileInputStream(mappingLog);

			OutputStream os = response.getOutputStream();
			byte[] b = new byte[2048];
			int length;
			while ((length = inputStream.read(b)) > 0) {
				os.write(b, 0, length);
			}
			// 这里主要关闭。
			os.close();
			inputStream.close();
		} catch (FileNotFoundException e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
		} catch (IOException e) {
			logger.error(e.getLocalizedMessage(), e.getClass());
		}
		// 返回值要注意，要不然就出现下面这句错误！
		// java+getOutputStream() has already been called for this response
		return null;
	}

}
